This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

library(ggplot2)
library(plotly)
package 㤼㸱plotly㤼㸲 was built under R version 4.0.4Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

Attaching package: 㤼㸱plotly㤼㸲

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    last_plot

The following object is masked from 㤼㸱package:stats㤼㸲:

    filter

The following object is masked from 㤼㸱package:graphics㤼㸲:

    layout
library(shiny)
package 㤼㸱shiny㤼㸲 was built under R version 4.0.4
library(dplyr)

Attaching package: 㤼㸱dplyr㤼㸲

The following objects are masked from 㤼㸱package:stats㤼㸲:

    filter, lag

The following objects are masked from 㤼㸱package:base㤼㸲:

    intersect, setdiff, setequal, union
source("./DataProccess.R")
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
-- Attaching packages ------------------------------------------------------------------------------------------------------------- tidyverse 1.3.0 --
v tibble  3.0.5     v purrr   0.3.4
v tidyr   1.1.2     v stringr 1.4.0
v readr   1.4.0     v forcats 0.5.0
-- Conflicts ---------------------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
x dplyr::filter() masks plotly::filter(), stats::filter()
x dplyr::lag()    masks stats::lag()

Attaching package: 㤼㸱lubridate㤼㸲

The following objects are masked from 㤼㸱package:base㤼㸲:

    date, intersect, setdiff, union


Attaching package: 㤼㸱zoo㤼㸲

The following objects are masked from 㤼㸱package:base㤼㸲:

    as.Date, as.Date.numeric
HFGData="../data/HFG data for stats preliminary 3-18-21.xlsx"

HFGFrame=HFGInfo(HFGData)%>%
  mutate("Filter Rep"=as.character(`Filter Rep`),`Well Rep`=as.character(`Well Rep`))
New names:
* `` -> ...2
HFGFrame.mean=HFGFrame%>%
  ungroup()%>%
  group_by(Date,`Filter Rep`,Plant)%>%
  summarise(N1GC=mean(N1GC))%>%
  ungroup()%>%
  filter(N1GC<10000000)
`summarise()` has grouped output by 'Date', 'Filter Rep'. You can override using the `.groups` argument.
HFGFrame.Filtered=HFGFrame%>%
  filter(N1GC<100000000)%>%
  filter(!is.na(N1GC),!is.na(Date))


HFGDFrame=HFGFrame.Filtered

p=ggplot()+
geom_jitter(data=HFGDFrame,aes(x=Date, y=N1GC , color=`Filter Rep`,text=Plant),size=1, position = position_jitter(width = .1, height = 0))+
  geom_smooth(data=HFGFrame.mean,aes(x=Date,y=N1GC, color=`Filter Rep`),se=F)
Ignoring unknown aesthetics: text
ggplotly(p,tooltip = c("text", "size"))
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
Jitter_POSIXlt = function (x, factor = 1, amount = 86400/4) 
{
    if (length(x) == 0L) 
        return(x)
    if (!is.POSIXlt(x)) 
        stop("'x' must be Date")
    x + stats::runif(length(x), -amount, amount)
}




#Data needs to be sorted by category being filtered
HFGDFrame2 <- HFGDFrame[order(HFGDFrame$`Filter Rep`), ]

Plants=unique(HFGDFrame$Plant)

button = list()
button[[1]] = list(method = "restyle",
               args = list("transforms[0].value", unique(HFGDFrame$Plant)),
               label = unique("All"))


for (i in 2:length(Plants)){
  button[[i]]=list(method = "restyle",
               args = list("transforms[0].value", unique(HFGDFrame$Plant)[i]),
               label = unique(HFGDFrame$Plant)[i])
}
fig <-HFGDFrame%>%
  plot_ly(
  x = Jitter_POSIXlt(as.POSIXlt(HFGDFrame$Date)),
  text = ~`Plant`,
  hoverinfo = 'text',
  transforms = list(
      list(
        type = 'filter',
        target = HFGDFrame2$Plant,
        operation = 'in',
        value = unique(HFGDFrame$Plant)[1]
      )
    )
)%>%
   add_trace(type = 'scatter',
              y = ~N1GC,
             color = ~`Filter Rep`,
             mode = 'markers') %>%
  add_lines(y = fitted(loess(N1GC ~ as.numeric(Date),data=HFGDFrame)),
            line = list(color = '#07A4B5'))%>%
  layout(
    updatemenus = list(
      list(
        type = 'dropdown',
        active = 0,
        buttons = button
      )
    )
  )
fig
#1)Best version of modeling
#2)Same scale-log Scale-some way to see outlines-once we see it in N1-look at N2 instead- CT variance-calibrate on one then shifts to other.
#3)graph variance per well
#L)N1 should not change much day to day-if it does->some issue with measurement->understand measurement to get good smooth->toss minority examples
#group by wells->summarize->group by filter->summarize->have estimate for day.
#or interquartile to get reasonable values->mean of those->mean W/O outlines
#compare change over time
#median of the replicates might be very useful
#one picture to justify medians
#median lines to show the rep are close-exuding outlines
#rank testing -rank them in order-to see if they are close
#multi-layered
#rep from filter-same distribution-rank all 9 compare largest and smallest
#LOOK AT PREVIOUS WORK
#Give them a things to look at
#prep them to get a good understanding
#Fix axis log scale
#lets them pick filter
#day to day variance

#Set day to work to work on repo
#friday?
ui <- fluidPage(
  titlePanel("Dashboard"),
  
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "Plant", label = ("Plant"),
                  choices = unique(HFGDFrame$Plant),
                  multiple=T 
      ),
      selectInput(inputId = "Line", label = ("Line Method"),
                  choices = c("None","Loess","mean value","Linear Model")
      )
    ),
    mainPanel(plotOutput("plot2"))
  )
)

                                        
server <- function(input, output) {
  filtered_data<- reactive({
    filter(HFGDFrame, HFGDFrame$Plant %in%  input$Plant)})
  Filtered_mean = reactive({
    filtered_data()%>%
      group_by(Date,`Filter Rep`)%>%
      summarize(N1GC=mean(N1GC))
  })
  output$plot2<-renderPlot({
    ggplot()+aes(x=Date,color=`Filter Rep`)+
      geom_jitter(data=filtered_data(),aes(y=N1GC,shape=Plant,fill=`Filter Rep`),height=0,width=.05)+
      scale_shape_manual(values=1:length(unique(HFGDFrame$Plant)))+
      geom_line(data=Filtered_mean(),aes(y=N1GC+ifelse(input$Line=="mean value",0,NA)),size=1)+
      geom_smooth(data=filtered_data(),aes(y=N1GC+ifelse(input$Line=="Loess",0,NA)),se=F)+
      geom_smooth(data=filtered_data(),method='lm',aes(y=N1GC+ifelse(input$Line=="Linear Model",0,NA)),se=F)+
      scale_y_log10(limits = c(min(HFGDFrame$N1GC),max(HFGDFrame$N1GC)))
      },height = 600,width = 800)
}

shinyApp(ui = ui, server = server)

Listening on http://127.0.0.1:7748
NA
Waterfilename <- "../data/WW SARS-COV-2 Data V5.xlsx"
CovidFileName = "../data/MMSD_Cases.csv"
source("./DataProccess.R")
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
-- Attaching packages ------------------------------------------------------------------------------------------------------------- tidyverse 1.3.0 --
v ggplot2 3.3.3     v purrr   0.3.4
v tibble  3.0.5     v dplyr   1.0.3
v tidyr   1.1.2     v stringr 1.4.0
v readr   1.4.0     v forcats 0.5.0
-- Conflicts ---------------------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()

Attaching package: 㤼㸱lubridate㤼㸲

The following objects are masked from 㤼㸱package:base㤼㸲:

    date, intersect, setdiff, union


Attaching package: 㤼㸱zoo㤼㸲

The following objects are masked from 㤼㸱package:base㤼㸲:

    as.Date, as.Date.numeric

Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     

Restarting R session...
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoc2hpbnkpDQpsaWJyYXJ5KGRwbHlyKQ0Kc291cmNlKCIuL0RhdGFQcm9jY2Vzcy5SIikNCg0KDQpIRkdEYXRhPSIuLi9kYXRhL0hGRyBkYXRhIGZvciBzdGF0cyBwcmVsaW1pbmFyeSAzLTE4LTIxLnhsc3giDQoNCkhGR0ZyYW1lPUhGR0luZm8oSEZHRGF0YSklPiUNCiAgbXV0YXRlKCJGaWx0ZXIgUmVwIj1hcy5jaGFyYWN0ZXIoYEZpbHRlciBSZXBgKSxgV2VsbCBSZXBgPWFzLmNoYXJhY3RlcihgV2VsbCBSZXBgKSkNCkhGR0ZyYW1lLm1lYW49SEZHRnJhbWUlPiUNCiAgdW5ncm91cCgpJT4lDQogIGdyb3VwX2J5KERhdGUsYEZpbHRlciBSZXBgLFBsYW50KSU+JQ0KICBzdW1tYXJpc2UoTjFHQz1tZWFuKE4xR0MpKSU+JQ0KICB1bmdyb3VwKCklPiUNCiAgZmlsdGVyKE4xR0M8MTAwMDAwMDApDQoNCg0KSEZHRnJhbWUuRmlsdGVyZWQ9SEZHRnJhbWUlPiUNCiAgZmlsdGVyKE4xR0M8MTAwMDAwMDAwKSU+JQ0KICBmaWx0ZXIoIWlzLm5hKE4xR0MpLCFpcy5uYShEYXRlKSkNCg0KDQpIRkdERnJhbWU9SEZHRnJhbWUuRmlsdGVyZWQNCg0KcD1nZ3Bsb3QoKSsNCmdlb21faml0dGVyKGRhdGE9SEZHREZyYW1lLGFlcyh4PURhdGUsIHk9TjFHQyAsIGNvbG9yPWBGaWx0ZXIgUmVwYCx0ZXh0PVBsYW50KSxzaXplPTEsIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gLjEsIGhlaWdodCA9IDApKSsNCiAgZ2VvbV9zbW9vdGgoZGF0YT1IRkdGcmFtZS5tZWFuLGFlcyh4PURhdGUseT1OMUdDLCBjb2xvcj1gRmlsdGVyIFJlcGApLHNlPUYpDQoNCg0KZ2dwbG90bHkocCx0b29sdGlwID0gYygidGV4dCIsICJzaXplIikpDQpgYGANCg0KDQpgYGB7cn0NCkppdHRlcl9QT1NJWGx0ID0gZnVuY3Rpb24gKHgsIGZhY3RvciA9IDEsIGFtb3VudCA9IDg2NDAwLzQpIA0Kew0KICAgIGlmIChsZW5ndGgoeCkgPT0gMEwpIA0KICAgICAgICByZXR1cm4oeCkNCiAgICBpZiAoIWlzLlBPU0lYbHQoeCkpIA0KICAgICAgICBzdG9wKCIneCcgbXVzdCBiZSBEYXRlIikNCiAgICB4ICsgc3RhdHM6OnJ1bmlmKGxlbmd0aCh4KSwgLWFtb3VudCwgYW1vdW50KQ0KfQ0KDQoNCg0KDQojRGF0YSBuZWVkcyB0byBiZSBzb3J0ZWQgYnkgY2F0ZWdvcnkgYmVpbmcgZmlsdGVyZWQNCkhGR0RGcmFtZTIgPC0gSEZHREZyYW1lW29yZGVyKEhGR0RGcmFtZSRgRmlsdGVyIFJlcGApLCBdDQoNClBsYW50cz11bmlxdWUoSEZHREZyYW1lJFBsYW50KQ0KDQpidXR0b24gPSBsaXN0KCkNCmJ1dHRvbltbMV1dID0gbGlzdChtZXRob2QgPSAicmVzdHlsZSIsDQogICAgICAgICAgICAgICBhcmdzID0gbGlzdCgidHJhbnNmb3Jtc1swXS52YWx1ZSIsIHVuaXF1ZShIRkdERnJhbWUkUGxhbnQpKSwNCiAgICAgICAgICAgICAgIGxhYmVsID0gdW5pcXVlKCJBbGwiKSkNCg0KDQpmb3IgKGkgaW4gMjpsZW5ndGgoUGxhbnRzKSl7DQogIGJ1dHRvbltbaV1dPWxpc3QobWV0aG9kID0gInJlc3R5bGUiLA0KICAgICAgICAgICAgICAgYXJncyA9IGxpc3QoInRyYW5zZm9ybXNbMF0udmFsdWUiLCB1bmlxdWUoSEZHREZyYW1lJFBsYW50KVtpXSksDQogICAgICAgICAgICAgICBsYWJlbCA9IHVuaXF1ZShIRkdERnJhbWUkUGxhbnQpW2ldKQ0KfQ0KZmlnIDwtSEZHREZyYW1lJT4lDQogIHBsb3RfbHkoDQogIHggPSBKaXR0ZXJfUE9TSVhsdChhcy5QT1NJWGx0KEhGR0RGcmFtZSREYXRlKSksDQogIHRleHQgPSB+YFBsYW50YCwNCiAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICB0cmFuc2Zvcm1zID0gbGlzdCgNCiAgICAgIGxpc3QoDQogICAgICAgIHR5cGUgPSAnZmlsdGVyJywNCiAgICAgICAgdGFyZ2V0ID0gSEZHREZyYW1lMiRQbGFudCwNCiAgICAgICAgb3BlcmF0aW9uID0gJ2luJywNCiAgICAgICAgdmFsdWUgPSB1bmlxdWUoSEZHREZyYW1lJFBsYW50KVsxXQ0KICAgICAgKQ0KICAgICkNCiklPiUNCiAgIGFkZF90cmFjZSh0eXBlID0gJ3NjYXR0ZXInLA0KICAgICAgICAgICAgICB5ID0gfk4xR0MsDQogICAgICAgICAgICAgY29sb3IgPSB+YEZpbHRlciBSZXBgLA0KICAgICAgICAgICAgIG1vZGUgPSAnbWFya2VycycpICU+JQ0KICBhZGRfbGluZXMoeSA9IGZpdHRlZChsb2VzcyhOMUdDIH4gYXMubnVtZXJpYyhEYXRlKSxkYXRhPUhGR0RGcmFtZSkpLA0KICAgICAgICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAnIzA3QTRCNScpKSU+JQ0KICBsYXlvdXQoDQogICAgdXBkYXRlbWVudXMgPSBsaXN0KA0KICAgICAgbGlzdCgNCiAgICAgICAgdHlwZSA9ICdkcm9wZG93bicsDQogICAgICAgIGFjdGl2ZSA9IDAsDQogICAgICAgIGJ1dHRvbnMgPSBidXR0b24NCiAgICAgICkNCiAgICApDQogICkNCmZpZw0KIzEpQmVzdCB2ZXJzaW9uIG9mIG1vZGVsaW5nDQojMilTYW1lIHNjYWxlLWxvZyBTY2FsZS1zb21lIHdheSB0byBzZWUgb3V0bGluZXMtb25jZSB3ZSBzZWUgaXQgaW4gTjEtbG9vayBhdCBOMiBpbnN0ZWFkLSBDVCB2YXJpYW5jZS1jYWxpYnJhdGUgb24gb25lIHRoZW4gc2hpZnRzIHRvIG90aGVyLg0KIzMpZ3JhcGggdmFyaWFuY2UgcGVyIHdlbGwNCiNMKU4xIHNob3VsZCBub3QgY2hhbmdlIG11Y2ggZGF5IHRvIGRheS1pZiBpdCBkb2VzLT5zb21lIGlzc3VlIHdpdGggbWVhc3VyZW1lbnQtPnVuZGVyc3RhbmQgbWVhc3VyZW1lbnQgdG8gZ2V0IGdvb2Qgc21vb3RoLT50b3NzIG1pbm9yaXR5IGV4YW1wbGVzDQojZ3JvdXAgYnkgd2VsbHMtPnN1bW1hcml6ZS0+Z3JvdXAgYnkgZmlsdGVyLT5zdW1tYXJpemUtPmhhdmUgZXN0aW1hdGUgZm9yIGRheS4NCiNvciBpbnRlcnF1YXJ0aWxlIHRvIGdldCByZWFzb25hYmxlIHZhbHVlcy0+bWVhbiBvZiB0aG9zZS0+bWVhbiBXL08gb3V0bGluZXMNCiNjb21wYXJlIGNoYW5nZSBvdmVyIHRpbWUNCiNtZWRpYW4gb2YgdGhlIHJlcGxpY2F0ZXMgbWlnaHQgYmUgdmVyeSB1c2VmdWwNCiNvbmUgcGljdHVyZSB0byBqdXN0aWZ5IG1lZGlhbnMNCiNtZWRpYW4gbGluZXMgdG8gc2hvdyB0aGUgcmVwIGFyZSBjbG9zZS1leHVkaW5nIG91dGxpbmVzDQojcmFuayB0ZXN0aW5nIC1yYW5rIHRoZW0gaW4gb3JkZXItdG8gc2VlIGlmIHRoZXkgYXJlIGNsb3NlDQojbXVsdGktbGF5ZXJlZA0KI3JlcCBmcm9tIGZpbHRlci1zYW1lIGRpc3RyaWJ1dGlvbi1yYW5rIGFsbCA5IGNvbXBhcmUgbGFyZ2VzdCBhbmQgc21hbGxlc3QNCiNMT09LIEFUIFBSRVZJT1VTIFdPUksNCmBgYA0KDQpgYGB7cn0NCiNHaXZlIHRoZW0gYSB0aGluZ3MgdG8gbG9vayBhdA0KI3ByZXAgdGhlbSB0byBnZXQgYSBnb29kIHVuZGVyc3RhbmRpbmcNCiNGaXggYXhpcyBsb2cgc2NhbGUNCiNsZXRzIHRoZW0gcGljayBmaWx0ZXINCiNkYXkgdG8gZGF5IHZhcmlhbmNlDQoNCiNTZXQgZGF5IHRvIHdvcmsgdG8gd29yayBvbiByZXBvDQojZnJpZGF5Pw0KdWkgPC0gZmx1aWRQYWdlKA0KICB0aXRsZVBhbmVsKCJEYXNoYm9hcmQiKSwNCiAgDQogIHNpZGViYXJMYXlvdXQoDQogICAgc2lkZWJhclBhbmVsKA0KICAgICAgc2VsZWN0SW5wdXQoaW5wdXRJZCA9ICJQbGFudCIsIGxhYmVsID0gKCJQbGFudCIpLA0KICAgICAgICAgICAgICAgICAgY2hvaWNlcyA9IHVuaXF1ZShIRkdERnJhbWUkUGxhbnQpLA0KICAgICAgICAgICAgICAgICAgbXVsdGlwbGU9VCANCiAgICAgICksDQogICAgICBzZWxlY3RJbnB1dChpbnB1dElkID0gIkxpbmUiLCBsYWJlbCA9ICgiTGluZSBNZXRob2QiKSwNCiAgICAgICAgICAgICAgICAgIGNob2ljZXMgPSBjKCJOb25lIiwiTG9lc3MiLCJtZWFuIHZhbHVlIiwiTGluZWFyIE1vZGVsIikNCiAgICAgICkNCiAgICApLA0KICAgIG1haW5QYW5lbChwbG90T3V0cHV0KCJwbG90MiIpKQ0KICApDQopDQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCnNlcnZlciA8LSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0KSB7DQogIGZpbHRlcmVkX2RhdGE8LSByZWFjdGl2ZSh7DQogICAgZmlsdGVyKEhGR0RGcmFtZSwgSEZHREZyYW1lJFBsYW50ICVpbiUgIGlucHV0JFBsYW50KX0pDQogIEZpbHRlcmVkX21lYW4gPSByZWFjdGl2ZSh7DQogICAgZmlsdGVyZWRfZGF0YSgpJT4lDQogICAgICBncm91cF9ieShEYXRlLGBGaWx0ZXIgUmVwYCklPiUNCiAgICAgIHN1bW1hcml6ZShOMUdDPW1lYW4oTjFHQykpDQogIH0pDQogIG91dHB1dCRwbG90MjwtcmVuZGVyUGxvdCh7DQogICAgZ2dwbG90KCkrYWVzKHg9RGF0ZSxjb2xvcj1gRmlsdGVyIFJlcGApKw0KICAgICAgZ2VvbV9qaXR0ZXIoZGF0YT1maWx0ZXJlZF9kYXRhKCksYWVzKHk9TjFHQyxzaGFwZT1QbGFudCxmaWxsPWBGaWx0ZXIgUmVwYCksaGVpZ2h0PTAsd2lkdGg9LjA1KSsNCiAgICAgIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9MTpsZW5ndGgodW5pcXVlKEhGR0RGcmFtZSRQbGFudCkpKSsNCiAgICAgIGdlb21fbGluZShkYXRhPUZpbHRlcmVkX21lYW4oKSxhZXMoeT1OMUdDK2lmZWxzZShpbnB1dCRMaW5lPT0ibWVhbiB2YWx1ZSIsMCxOQSkpLHNpemU9MSkrDQogICAgICBnZW9tX3Ntb290aChkYXRhPWZpbHRlcmVkX2RhdGEoKSxhZXMoeT1OMUdDK2lmZWxzZShpbnB1dCRMaW5lPT0iTG9lc3MiLDAsTkEpKSxzZT1GKSsNCiAgICAgIGdlb21fc21vb3RoKGRhdGE9ZmlsdGVyZWRfZGF0YSgpLG1ldGhvZD0nbG0nLGFlcyh5PU4xR0MraWZlbHNlKGlucHV0JExpbmU9PSJMaW5lYXIgTW9kZWwiLDAsTkEpKSxzZT1GKSsNCiAgICAgIHNjYWxlX3lfbG9nMTAobGltaXRzID0gYyhtaW4oSEZHREZyYW1lJE4xR0MpLG1heChIRkdERnJhbWUkTjFHQykpKQ0KICAgICAgfSxoZWlnaHQgPSA2MDAsd2lkdGggPSA4MDApDQp9DQoNCnNoaW55QXBwKHVpID0gdWksIHNlcnZlciA9IHNlcnZlcikNCg0KDQpgYGANCg0KDQpgYGB7cn0NCldhdGVyZmlsZW5hbWUgPC0gIi4uL2RhdGEvV1cgU0FSUy1DT1YtMiBEYXRhIFY1Lnhsc3giDQpDb3ZpZEZpbGVOYW1lID0gIi4uL2RhdGEvTU1TRF9DYXNlcy5jc3YiDQpzb3VyY2UoIi4vRGF0YVByb2NjZXNzLlIiKQ0KbGlicmFyeShqYW5pdG9yKQ0Kd2F0ZXI9V2FzdGVXYXRlcihXYXRlcmZpbGVuYW1lKQ0KDQp3YXRlcl9IYWNrSm9iPXdhdGVyJT4lDQogIGZpbHRlcihzdHJfY291bnQoRGF0ZSwiXFwuIik9PTApJT4lDQogIGZpbHRlcihzdHJfY291bnQoRGF0ZSwiLyIpPT0wKSU+JQ0KICBtdXRhdGUoRGF0ZT1leGNlbF9udW1lcmljX3RvX2RhdGUoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoRGF0ZSkpLCBkYXRlX3N5c3RlbSA9ICJtb2Rlcm4iKSApJT4lDQogIGZpbHRlcihTaXRlIT0iVVctU2VsbGVyeSIsU2l0ZSE9IlVXLUxha2VTaG9yZSIpDQoNCg0KY292aWREYXRhPUNvdmlkRGF0YShDb3ZpZEZpbGVOYW1lKQ0KRnVsbERhdGE9ZnVsbF9qb2luKHdhdGVyX0hhY2tKb2IsY292aWREYXRhLGJ5PWMoIkRhdGUiLCJTaXRlIikpDQoNCg0KdWkgPC0gZmx1aWRQYWdlKA0KICB0aXRsZVBhbmVsKCJEYXNoYm9hcmQiKSwNCiAgDQogICMgU2lkZWJhciB3aXRoIGEgc2xpZGVyIGlucHV0IGZvciBudW1iZXIgb2YgYmlucyANCiAgc2lkZWJhckxheW91dCgNCiAgICBzaWRlYmFyUGFuZWwoDQogICAgICBzZWxlY3RJbnB1dChpbnB1dElkID0gIlNpdGUiLCBsYWJlbCA9ICgiU2l0ZSIpLA0KICAgICAgICAgICAgICAgICAgY2hvaWNlcyA9IHVuaXF1ZShGdWxsRGF0YSRTaXRlKQ0KICAgICAgKSwNCiAgICAgIHNsaWRlcklucHV0KCJPZmZzZXQiLCAiT2Zmc2V0IixtaW4gPSAtMTAsIG1heCA9IDEwLHN0ZXA9MSx2YWx1ZT0wKQ0KICAgICAgKSwNCiAgICBtYWluUGFuZWwocGxvdE91dHB1dCgicGxvdDIiKSkNCiAgKQ0KKQ0KDQoNCiMgRGVmaW5lIHNlcnZlciBsb2dpYyByZXF1aXJlZCB0byBkcmF3IGEgaGlzdG9ncmFtDQpzZXJ2ZXIgPC0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCkgew0KICANCiAgd2F0ZXJfc2hpZnRlZD1yZWFjdGl2ZSh7DQogICAgbXV0YXRlKHdhdGVyX0hhY2tKb2IsRGF0ZT1EYXRlK2lucHV0JE9mZnNldCkNCiAgICANCiAgfSkNCiAgRnVsbERhdGE9cmVhY3RpdmUoew0KICAgIGZ1bGxfam9pbih3YXRlcl9zaGlmdGVkKCksY292aWREYXRhLGJ5PWMoIkRhdGUiLCJTaXRlIikpJT4lDQogICAgICBmaWx0ZXIoU2l0ZT09aW5wdXQkU2l0ZSkNCiAgfSkNCiAgTE09cmVhY3RpdmUoew0KICAgICAgbG0ocm9sbCB+IGxvZyhOMSkrbG9nKFBNTW9WKSxkYXRhPUZ1bGxEYXRhKCksbmEuYWN0aW9uID0gbmEuZXhjbHVkZSkNCiAgfSkNCiAgDQogIExNRkRhdGE8LSByZWFjdGl2ZSh7DQogICAgbXV0YXRlKEZ1bGxEYXRhKCksRml0dGVkPWZpdHRlZChMTSgpKSkNCiAgfSkNCiAgDQogIG91dHB1dCRwbG90MjwtcmVuZGVyUGxvdCh7DQogICAgZ2dwbG90KGRhdGE9TE1GRGF0YSgpKStnZW9tX3BvaW50KGFlcyh4PURhdGUseT1yb2xsKSkrDQogICAgICBnZW9tX3BvaW50KGFlcyh4PURhdGUseT1GaXR0ZWQpLGNvbG9yPSJyZWQiKSsNCiAgICAgIGFubm90YXRlKCJ0ZXh0IiwgeCA9IG1heChjb3ZpZERhdGEkRGF0ZSktMTAsIHkgPSAuMDAxLCBsYWJlbCA9IHJvdW5kKHN1bW1hcnkoTE0oKSkkci5zcXVhcmVkLDMpKQ0KICAgIA0KICAgIH0saGVpZ2h0ID0gNDAwLHdpZHRoID0gNjAwKQ0KfQ0KDQoNCnNoaW55QXBwKHVpID0gdWksIHNlcnZlciA9IHNlcnZlcikNCmBgYA0KDQoNCg==